home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / gottlieb.c < prev    next >
C/C++ Source or Header  |  2000-04-04  |  7KB  |  256 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7. ***************************************************************************/
  8.  
  9. #include "driver.h"
  10. #include "common.h"
  11. #include "vidhrdw/generic.h"
  12.  
  13.  
  14.  
  15. unsigned char *gottlieb_characterram;
  16. #define MAX_CHARS 256
  17. static unsigned char *dirtycharacter;
  18. static int background_priority=0;
  19. static unsigned char hflip=0;
  20. static unsigned char vflip=0;
  21. static int spritebank;
  22.  
  23.  
  24.  
  25. /***************************************************************************
  26.  
  27.   Gottlieb games dosn't have a color PROM. They use 32 bytes of RAM to
  28.   dynamically create the palette. Each couple of bytes defines one
  29.   color (4 bits per pixel; the high 4 bits of the second byte are unused).
  30.  
  31.   The RAM is conected to the RGB output this way:
  32.  
  33.   bit 7 -- 240 ohm resistor  -- GREEN
  34.         -- 470 ohm resistor  -- GREEN
  35.         -- 1  kohm resistor  -- GREEN
  36.         -- 2  kohm resistor  -- GREEN
  37.         -- 240 ohm resistor  -- RED
  38.         -- 470 ohm resistor  -- RED
  39.         -- 1  kohm resistor  -- RED
  40.   bit 0 -- 2  kohm resistor  -- RED
  41.  
  42.   bit 7 -- unused
  43.         -- unused
  44.         -- unused
  45.         -- unused
  46.         -- 240 ohm resistor  -- BLUE
  47.         -- 470 ohm resistor  -- BLUE
  48.         -- 1  kohm resistor  -- BLUE
  49.   bit 0 -- 2  kohm resistor  -- BLUE
  50.  
  51. ***************************************************************************/
  52. WRITE_HANDLER( gottlieb_paletteram_w )
  53. {
  54.     int bit0,bit1,bit2,bit3;
  55.     int r,g,b,val;
  56.  
  57.  
  58.     paletteram[offset] = data;
  59.  
  60.     /* red component */
  61.     val = paletteram[offset | 1];
  62.     bit0 = (val >> 0) & 0x01;
  63.     bit1 = (val >> 1) & 0x01;
  64.     bit2 = (val >> 2) & 0x01;
  65.     bit3 = (val >> 3) & 0x01;
  66.     r = 0x10 * bit0 + 0x21 * bit1 + 0x46 * bit2 + 0x88 * bit3;
  67.  
  68.     /* green component */
  69.     val = paletteram[offset & ~1];
  70.     bit0 = (val >> 4) & 0x01;
  71.     bit1 = (val >> 5) & 0x01;
  72.     bit2 = (val >> 6) & 0x01;
  73.     bit3 = (val >> 7) & 0x01;
  74.     g = 0x10 * bit0 + 0x21 * bit1 + 0x46 * bit2 + 0x88 * bit3;
  75.  
  76.     /* blue component */
  77.     val = paletteram[offset & ~1];
  78.     bit0 = (val >> 0) & 0x01;
  79.     bit1 = (val >> 1) & 0x01;
  80.     bit2 = (val >> 2) & 0x01;
  81.     bit3 = (val >> 3) & 0x01;
  82.     b = 0x10 * bit0 + 0x21 * bit1 + 0x46 * bit2 + 0x88 * bit3;
  83.  
  84.     palette_change_color(offset / 2,r,g,b);
  85. }
  86.  
  87.  
  88.  
  89. /***************************************************************************
  90.  
  91.   Start the video hardware emulation.
  92.  
  93. ***************************************************************************/
  94.  
  95. int gottlieb_vh_start(void)
  96. {
  97.     if (generic_vh_start() != 0)
  98.         return 1;
  99.  
  100.     if ((dirtycharacter = malloc(MAX_CHARS)) == 0)
  101.     {
  102.         generic_vh_stop();
  103.         return 1;
  104.     }
  105.     /* Some games have character gfx data in ROM, some others in RAM. We don't */
  106.     /* want to recalculate chars if data is in ROM, so let's start with the array */
  107.     /* initialized to 0. */
  108.     memset(dirtycharacter,0,MAX_CHARS);
  109.  
  110.     return 0;
  111. }
  112.  
  113. /***************************************************************************
  114.  
  115.   Stop the video hardware emulation.
  116.  
  117. ***************************************************************************/
  118. void gottlieb_vh_stop(void)
  119. {
  120.     free(dirtycharacter);
  121.     generic_vh_stop();
  122. }
  123.  
  124.  
  125.  
  126. WRITE_HANDLER( gottlieb_video_outputs_w )
  127. {
  128.     extern void gottlieb_knocker(void);
  129.     static int last = 0;
  130.  
  131.  
  132.     background_priority = data & 1;
  133.  
  134.     hflip = data & 2;
  135.     vflip = data & 4;
  136.     if ((data & 6) != (last & 6))
  137.         memset(dirtybuffer,1,videoram_size);
  138.  
  139.     /* in Q*Bert Qubes only, bit 4 controls the sprite bank */
  140.     spritebank = (data & 0x10) >> 4;
  141.  
  142.     if ((last&0x20) && !(data&0x20)) gottlieb_knocker();
  143.  
  144.     last = data;
  145. }
  146.  
  147. WRITE_HANDLER( usvsthem_video_outputs_w )
  148. {
  149.     background_priority = data & 1;
  150.  
  151.     /* in most games, bits 1 and 2 flip screen, however in the laser */
  152.     /* disc games they are different. */
  153.  
  154.     /* bit 1 controls the sprite bank. */
  155.     spritebank = (data & 0x02) >> 1;
  156.  
  157.     /* bit 2 video enable (0 = black screen) */
  158.  
  159.     /* bit 3 genlock control (1 = show laserdisc image) */
  160. }
  161.  
  162.  
  163.  
  164. WRITE_HANDLER( gottlieb_characterram_w )
  165. {
  166.     if (gottlieb_characterram[offset] != data)
  167.     {
  168.         dirtycharacter[offset / 32] = 1;
  169.         gottlieb_characterram[offset] = data;
  170.     }
  171. }
  172.  
  173.  
  174.  
  175. /***************************************************************************
  176.  
  177.   Draw the game screen in the given osd_bitmap.
  178.   Do NOT call osd_update_display() from this function, it will be called by
  179.   the main emulation engine.
  180.  
  181. ***************************************************************************/
  182. void gottlieb_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  183. {
  184.     int offs;
  185.  
  186.  
  187.     /* update palette */
  188.     if (palette_recalc())
  189.         memset(dirtybuffer, 1, videoram_size);
  190.  
  191.     /* recompute character graphics */
  192.     for (offs = 0;offs < Machine->drv->gfxdecodeinfo[0].gfxlayout->total;offs++)
  193.     {
  194.         if (dirtycharacter[offs])
  195.             decodechar(Machine->gfx[0],offs,gottlieb_characterram,Machine->drv->gfxdecodeinfo[0].gfxlayout);
  196.     }
  197.  
  198.  
  199.     /* for every character in the Video RAM, check if it has been modified */
  200.     /* since last time and update it accordingly. */
  201.     for (offs = videoram_size - 1;offs >= 0;offs--)
  202.     {
  203.         if (dirtybuffer[offs] || dirtycharacter[videoram[offs]])
  204.         {
  205.             int sx,sy;
  206.  
  207.  
  208.             dirtybuffer[offs] = 0;
  209.  
  210.             sx = offs % 32;
  211.             sy = offs / 32;
  212.             if (hflip) sx = 31 - sx;
  213.             if (vflip) sy = 29 - sy;
  214.  
  215.             drawgfx(tmpbitmap,Machine->gfx[0],
  216.                     videoram[offs],
  217.                     0,
  218.                     hflip,vflip,
  219.                     8*sx,8*sy,
  220.                     &Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  221.         }
  222.     }
  223.  
  224.     memset(dirtycharacter,0,MAX_CHARS);
  225.  
  226.  
  227.     /* copy the character mapped graphics */
  228.     copybitmap(bitmap,tmpbitmap,0,0,0,0,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  229.  
  230.  
  231.     /* Draw the sprites. Note that it is important to draw them exactly in this */
  232.     /* order, to have the correct priorities. */
  233.     for (offs = 0;offs < spriteram_size - 8;offs += 4)     /* it seems there's something strange with sprites #62 and #63 */
  234.     {
  235.         int sx,sy;
  236.  
  237.  
  238.         /* coordinates hand tuned to make the position correct in Q*Bert Qubes start */
  239.         /* of level animation. */
  240.         sx = (spriteram[offs + 1]) - 4;
  241.         if (hflip) sx = 233 - sx;
  242.         sy = (spriteram[offs]) - 13;
  243.         if (vflip) sy = 228 - sy;
  244.  
  245.         if (spriteram[offs] || spriteram[offs + 1])    /* needed to avoid garbage on screen */
  246.             drawgfx(bitmap,Machine->gfx[1],
  247.                     (255 ^ spriteram[offs + 2]) + 256 * spritebank,
  248.                     0,
  249.                     hflip,vflip,
  250.                     sx,sy,
  251.                     &Machine->drv->visible_area,
  252.                     background_priority ? TRANSPARENCY_THROUGH : TRANSPARENCY_PEN,
  253.                     background_priority ? Machine->pens[0]     : 0);
  254.     }
  255. }
  256.